Commit Graph
23581 Commits
Author SHA1 Message Date
imccyu 261f2db185 Merge master into DSH 0.2.1 navigation and model listing sync 2026-10-22 23:22:35 +08:00
Xu Hanxiang 70e2d31cc3 Merge pull request #6486 from deepseek-harness/feat/client-extension-points
feat(liveshare): add client and host seams a served read-only page needs
2026-10-22 22:57:27 +08:00
mektpoy 76e39794eb revert(ui-session,ui-conversation): let the stop shortcut reach the Host
A reviewer blocked the one-shot boolean access read the stop shortcut used:
the client should not expose a render-time access answer as a boolean API.
The Esc-Esc sequence submits its cancel again, and a Host refusal surfaces as
the composer failure the Stop button would have prevented. Send keeps the same
treatment: the access snapshot withholds the buttons, the Host refuses the
request, and the composer reports it.
2026-10-22 22:16:06 +08:00
mektpoy 80ce0669e9 revert(ui-conversation): leave a withheld submission to the Host
The access snapshot still withholds the Send button, Stop, and file intake, and
the Esc-Esc stop path still reads its own answer before sending a cancel. A
keyboard submission, however, once again reaches the Host, which refuses it and
reports the failure to the composer; gating that path needs a larger redesign
of the composer keyboard face.
2026-10-22 21:57:49 +08:00
mektpoy d9c012551a revert(client): return the fork seam to master
ui-chat goes back to origin/master as a whole package: the footer branch forks
through ctx.sessions.fork with its own atSeq and analytics again, and Workspace
navigation takes no ForkSessionOptions. The package is identical to
origin/master, which drops the served-page branch assertions and README lines
added on this branch; they pinned behavior master already has.

ui-workspace restores master's forkSession signature and implementation
(allowMigration only, increaseTitle: true, selection untouched) and drops the
ForkSessionOptions type. uiSession leaves the inject list because the removed
session/rename probe was its only consumer. The row fork keeps passing
{ allowMigration: false }, which master already does, so forking from a shared
page never starts source-format migration.

Regenerate the client API catalog, restore the README fork contract (fork does
not navigate; allowMigration carries migration permission), re-record the
translation pairing, and return the ui-chat unknown-cast baseline count to 2.
2026-10-22 21:44:25 +08:00
mektpoy 58785b975e fix(ui-workspace): name every branch and open it on request
`increaseTitle` renames the child, not the source, and whoever may fork a Session also holds `session/rename` on the child it creates; the source's access answer therefore never decides the child's title. Remove the source-rename probe, the listed-branch wait, and its refresh-failure notice: `selected` opens the child immediately and `listed` leaves the selection alone. Update the public READMEs and the client API catalog.
2026-10-22 21:44:25 +08:00
mektpoy 0b72a81411 chore(docs): re-record the conversation README pairing after the master rebase 2026-10-22 21:44:25 +08:00
mektpoy 3ecac5aad4 chore(catalogs): follow the branch contract and Session access edits
Regenerate the client API catalog after the forkSession contract and the
ui-workspace gating changes.
2026-10-22 21:44:25 +08:00
mektpoy d985f44124 chore(ui-chat): correct the branch-rejection test comment
A rejected branch leaves the source view unchanged, as master does; the old
comment described the removed notice.
2026-10-22 21:44:25 +08:00
mektpoy 3bcb22f732 fix(ui-conversation): gate keyboard submission and stop
Enter, Mod+Enter, and accelerated queue steering now read the same prompt
answer as the Send button, and the fixed Esc-Esc sequence reads the live
session/cancel answer before it consumes a press. The composer locks for a
denied prompt, the README states both paths, and tests pin each gesture.
2026-10-22 21:44:25 +08:00
mektpoy cfc2fd926e fix(ui-workspace): route row gates through the Session service
Read the branch-naming answer through uiSession.access instead of the
cross-kind source, drop the unused openListedBranch method, give the branch
list refresh its own notice, and gate the search result restore control like
the archive row. The forkSession contract now states its navigation and throws
behaviour, present documents its 2x2 landing table, and the README describes
the real branch policy and row gating.
2026-10-22 21:44:25 +08:00
mektpoy f0fcd68b7b feat(ui-session): answer Session access for JS callers
The Session kind owns its remoteAccess source, so other plugins get one
non-Hook read from this service instead of reading the source themselves.
Navigation uses it for the branch-naming answer.
2026-10-22 21:44:25 +08:00
mektpoy b1f10381cb fix(ui-deliverables): return the package to master
The owner-baseline gate this branch added has no reader on the master access
API, and the reader page reads files through the Host route instead.
2026-10-22 21:44:25 +08:00
mektpoy 491515268a chore(docs): regenerate the cordis catalog after the frontend-static simplification 2026-10-22 21:44:25 +08:00
mektpoy c3f2fbbdad chore(client): follow the merged seam records in generated artifacts
The client inspect catalog follows the seam signatures, the unknown-cast
baseline drops the two casts this branch retired, and the README pairing
records match the merged prose.
2026-10-22 21:44:25 +08:00
mektpoy 55deb7a6c6 fix(ui-workspace): keep the per-resource access gates on the whenAccess client
Master's rows and menus carry no answer of their own, so the served-page seams
thread the Slot-standard access Hooks through the workspace browser and the
session actions: New Session, workspace rename/delete/reorder, and a Session's
rename, pin, archive, and reorder appear only while their own resource allows
them. The rows spec keeps master's pointer-armed rename helper and supplies the
allow-all answers as props.
2026-10-22 21:44:25 +08:00
imccyu 0d521bdd0d refactor(client): drop owner-era leftovers and gate sidebar New Session on session/create
- The Conversation binding tracking returns to master: the retainInfo subscription and the
  plugin-owned binding effects are a separate fix, not a served-page seam.
- The deliverables opener drops the ownerHostRoutes parameter no caller passes any more.
- Assertions on existing connection and HMR behavior, the menu-open-state spec, and the
  settings-general roster splice return to master.
- Workspace shortcuts no longer re-read Session access through source(); the Host refuses a
  denied rename, fork, or archive.
- The sidebar New Session button, the window-chrome New Session control, and the expanded
  brand shortcut render only while useRemoteAccess('session/create') allows it.
2026-10-22 21:44:25 +08:00
imccyu a154f70ab9 refactor(client): read composer access through useAccess and drop the branch-refusal notice
- The composer decides file intake from the Session-scope useAccess('fileUploads/upload')
  answer, like Send and Stop. The optional fileIntake hook seat, the InputHub fileIntake
  entries, and the ui-slots optional-hook typing are removed.
- The fixed Stop shortcut no longer re-reads session/cancel through a shared stop; the
  button stays hidden by useAccess and the Host refuses a withdrawn cancel.
- uiConversation.noticeBranchRefusal, branch.ts, ForkRefusal, and message.branchRefused are
  removed; a failed Chat branch leaves the source view unchanged, as on master.
2026-10-22 21:44:25 +08:00
mektpoy e30684cf9c fix(client): keep the served-page records on the master access API
The owner-baseline gating commits are superseded by master's whenAccess seams,
so the remaining records revert to the master shapes: the deliverables opener
takes no owner answer, the Japanese dictionaries carry the surviving copy, and
the test splice and owner assertions match the current services.
2026-10-22 21:44:25 +08:00
mektpoy 82ed6eee99 fix(ui-chat): narrow the injected Chat View without an unknown assertion
Read the slot injection through its real rest-parameter function type and invoke it directly, so the static gate sees no new assertion to unknown. The client inspect catalog's expected uiWorkspace signature follows the generated catalog after the fork options became ForkSessionOptions.
2026-10-22 21:44:25 +08:00
mektpoy b191c5c865 revert(session-controller): restore the package to master
P1 keeps only the client/host extension seams; the requestId deduplication,
the cancel recheck, and the named fork child are deferred to a later change.
The package, its README pair, and the persistence schema lines return to the
master state, so the branch adds no session-controller behaviour.
2026-10-22 21:44:25 +08:00
mektpoy 1624faeb23 fix(ui-conversation): keep the released-binding and shared-stop edges
Type the tracked binding disposers by their real shape and let a disposed
context's shared stop surface its own loud unavailable error instead of
reporting a withdrawn permission.
2026-10-22 21:44:25 +08:00
mektpoy fbc90909b1 fix(ui-conversation): gate the fixed stop shortcut through the shared stop
The button re-read the live session/cancel answer but the fixed shortcut
received the raw stop, so a withdrawal still sent Esc-Esc cancellation. Build
one gated stop used by both entry points and cover the shared gate.
2026-10-22 21:44:25 +08:00
mektpoy 938e82484f fix(ui-conversation): narrow a fork rejection before reading its code
A rejection may be null, undefined, or any non-object; reading rpcError through
it threw a TypeError and replaced the branch-refusal notice with a crash. Narrow
the value first and cover the non-object rejections.
2026-10-22 21:44:24 +08:00
mektpoy 15ab556c3e fix(ui-conversation): release each binding effect with its Session scope
The long-lived plugin effect wrapped every Session-scope effect, so a released
binding's Context stayed referenced until plugin unload. Track the binding-scope
effects in a map that the binding cleanup and the plugin unload both drain;
nothing long-lived closes over a released binding.
2026-10-22 21:44:24 +08:00
mektpoy 44f0996974 fix(session-controller): ask the concrete access decision before cancelling
The recheck used allows(), the list-filter view that never sees call arguments,
so a policy narrowing cancel to args.request refused a legitimate caller as
access-withdrawn forever. Ask decide() with the principal and the request, keep
the policy's own refusal reason, and cover both an args-independent role and an
args-dependent condition.
2026-10-22 21:44:24 +08:00
mektpoy 258ff28b72 fix(session-controller): finish the Workspace attach a named fork left pending
A first attempt that materialized the child and then failed at attachSession
was reported as failed, but its retry adopted the stored child and returned
success before attaching it, leaving the child ungrouped. The adoption path now
completes the missing attach and reports the same session/workspace-attach-failed
if that still rejects.
2026-10-22 21:44:24 +08:00
mektpoy 608f08ab31 refactor(session-controller): drop the prompt pre-delivery access recheck
The Gateway already admits each call; P1 no longer re-reads the caller's access
after prompt admission. Cancellation still refuses delivery when the caller
aborts during admission, and the requestId dedup/conflict, cancel recheck, and
fork naming behavior stay. The README pair follows.
2026-10-22 21:44:24 +08:00
mektpoy 4322b97840 refactor(ui-workspace): own the branch naming and listed presentation
The published UiWorkspace no longer requires openListedBranch: that wait is an
internal navigation helper, and the service forkSession takes the branch
boundary and presentation choice as optional inputs. The Chat branch surface
now supplies only its branch point and analytics and lets Workspace navigation
decide whether the child may be named and when it becomes presentable.
2026-10-22 21:44:24 +08:00
mektpoy 5ff6b3cdc5 test(ui-chat): pin the owner page branch-refusal notice
A refused branch now reports itself on the owner's own page: the Chat
injection writes the notice on the addressed Session and the composer bar
renders it as an alert, so the owner-visible change has an assertion at both
seams.
2026-10-22 21:44:24 +08:00
mektpoy 52b2bd064f refactor(ui-conversation): read file intake through one InputHub entry
The composer hook source and the drop gate now resolve the same live intake
answer from InputHub, so the policy and its two readers cannot drift; the
caller keeps ownership of the rejection copy.
2026-10-22 21:44:24 +08:00
mektpoy 3660cb0ed6 refactor(ui-conversation): make the composer file-intake hook optional
A bar registration that cannot prove live file-intake permission omits the
source; the bar then offers no file controls, matching the no-session
placeholder's fail-closed answer. PropsHooks keeps required hook seats intact
and lets an optional source leave its seat undefined.
2026-10-22 21:44:24 +08:00
mektpoy 59817cf0b3 refactor(ui-conversation): keep the notice store off the published SessionInput
The composer notice store has no production reader through the published
SessionInput seam: the bar renders it through ComposerBarInjected.hooks.notices
and the only other reader was a test. Leave the store on SessionInputShell,
which the hook wiring uses, and assert the bar's hook in the Chat spec so the
contract surface only publishes members with real consumers.
2026-10-22 21:44:24 +08:00
mektpoy 61ec76af1f docs(ui-workspace): state the connectWorkspace contract once
The model-visible catalog inherited two versions of the same JSDoc sentence,
one of which contradicted the other. Describe the blank reuse once: the first
reusable listed blank, the requested preset or its default, one shared attempt
per Workspace and preset. The generated client inspect catalog follows.
2026-10-22 21:44:24 +08:00
mektpoy bbccdd5141 test(api): cover the prompt access recheck and the named fork paths
Close the Session Controller's remaining per-file coverage debt: a named
fork adopting the child its earlier attempt stored, refusing a name another
Session holds or one seeded at a different cut, and the named-child
observation failures; prompt admission sharing one in-flight requestId and
refusing a duplicate from another caller; the retry read from a drained
splice; the access-withdrawn and aborted-admission delivery paths; cancel
after the caller's grant is gone; and the Assistant settlement that appends
past the last entry. Test-only: no production behavior changed.
2026-10-22 21:44:24 +08:00
mektpoy b9861ae39d feat(api): re-check prompt access and name fork children
The Gateway admits a prompt before the controller sees it, so a binding narrowed while the prompt waited must not still deliver: the Remote method passes a predicate that re-reads the caller's access after every await and immediately before delivery, and cancel re-reads it in the same synchronous step. One requestId still produces one message; a retry from another principal is refused as session/request-conflict. Fork callers may name childSessionId so an interrupted attempt resumes the child it stored; any other occupant of that id is refused as session/fork-conflict. The agent-controller admission pipeline this previously built on is not part of the current master, so the prompt keeps the direct admission path and the tool-execution turn carrier is gone.
2026-10-22 21:44:24 +08:00
mektpoy 6475f57942 feat(client): publish the branch, slot, and access seams a served page reads
The Workspace tree gains the Host-published branch projection plus the
access-snapshot reads its rows, menu entries, and shortcuts consult; the
Conversation package moves branch handling into its own module and exposes the
input and slot declarations a page-local plugin composes. Chat, sidebar,
deliverables, and open-in-app publish the slot surfaces those readers fill, and
the document-relative route and HMR endpoint seams keep the served page's own
base.
2026-10-22 21:44:24 +08:00
Turtle d10f417f13 Merge pull request #6979 from deepseek-harness/turtle/rename-plugin-index-again-2424dbab6ad1
fix(plugin-market): present custom plugin markets as custom plugin indexes
2026-10-22 21:10:29 +08:00
Yichen Jiang c48f8523f2 feat(llm): follow the official /models listing on the DeepSeek API-key route (#6944)
* refactor(llm-deepseek): share the /models listing machinery

Move the account route's `/models` request and decoding, its
credential-scoped listing cache, and listed-catalog resolution with the
version gate into the shared DeepSeek Messages library, so a second
route can follow the same listing. Names drop the account prefix, the
cache takes each access's endpoint settings with the call, and it gains
`invalidate()` for a forced reload. `isBuiltInCatalog()` recognizes the
catalog an uncustomized `models` setting resolves to.

The account route keeps its behavior; only its imports and the
override diagnostic wording ("model listing") change.

* feat(llm-deepseek-api-key): follow the official /models listing

While `models` equals the built-in catalog and the Messages origin is
https://api.deepseek.com, `deepseek-official` serves the official
`GET /models` listing, authenticated with the API key in `x-api-key`.
Loading, refresh, fallback, merging, and the client-version gate match
the account route: the first access waits up to `modelsTimeoutMs`, a
listing older than `modelsMaxAgeMs` refreshes in the background on the
next access, a failure keeps the last good listing or the built-in
catalog, and listed models this build cannot serve are refused before
network I/O.

A customized `models` list replaces the catalog and requests nothing.
Switching between a customized catalog and the listing discards the
cached listing, so Restore defaults reloads it on the next access.

Suites that boot the route on the official endpoint now answer the
listing themselves instead of reaching the network.

* docs: describe the official route model listing

Document when `deepseek-official` follows the official `/models`
listing, its timing fields, customization precedence, and the forced
reload after Restore defaults in the API-key README, the shared
transport README, and the provider guide. Record the decision in a new
Agent Note, keep the account note's statement of where the shared
listing code lives current, and regenerate the configuration catalog.

* test(llm-deepseek-api-key): pin the once-per-listing hidden-entry diagnostic

* docs: regenerate module and event graphs for the shared listing

* fix(llm-deepseek-api-key): report credential failures on the model request

On the official endpoint, `connect` waited for the listing view, whose
credential lookup rethrew a malformed key or a credential-store failure
before the agent loop recorded the prompt. A failed lookup now resolves
the connection from the current listing view, so `resolveAuth` reports
the failure on the model request and the turn keeps the prompt and the
failed attempt. A caller abort still rejects.

* docs(llm-deepseek-api-key): name which hidden listing entries are logged

* test: keep unit suites off the official model listing

Suites that boot the DeepSeek routes with a dummy or inherited key now
request `GET https://api.deepseek.com/models` on the official endpoint.
A unit-lane setup file rejects that request at once, so such a suite
serves the built-in catalog instead of reaching production or waiting
out the listing deadline on a network that never answers; suites that
exercise the listing answer `fetch` themselves. Other requests pass
through unchanged.

* feat(llm-deepseek): read tool_update from the model listing

Both DeepSeek routes now take a listed model's Messages tool update mode
from `api_capabilities.anthropic_messages.tool_update`, alongside the
system prompt mode. `in-history` and `addition-only` replace the
bundled mode; any other value reads as `leading-only` and removes it.
An absent or `null` mode keeps the bundled one, so a listing that does
not declare the field leaves `deepseek-flash` on `addition-only`.

`system_prompt_update: null` likewise keeps the bundled mode now; it
previously read as `leading-only`, which a serializer writing empty
values as null would have turned into a cache-unfriendly downgrade.

* fix(llm-deepseek): sync the built-in context window with the official listing

The official `/models` listing declares a 1,048,576-token context window
for `deepseek-flash` and `deepseek-v4-pro`; the built-in catalog said
1,000,000, a decimal-versus-binary mismatch. Both built-in entries now
carry the listed value, so offline starts and listing failures size the
context the same way the listing does. The Models page shows the exact
count for these rows, since 1,048,576 has no decimal K/M spelling.

`defaultContextWindow`, the fallback for model ids the catalog does not
describe, stays 1,000,000.

* test(llm-deepseek-api-key): reject the stubbed listing request with an Error

* test(cli): keep the built SDK smoke off the official model listing

The SDK profile's initialize now resolves the deepseek-official catalog,
which requests GET https://api.deepseek.com/models on the official
endpoint. With the smoke's fixture key that request answers 401 and the
route warns on stderr, so the test's empty-stderr assertion failed in the
e2e and snapshots lanes. Point the run at a loopback mock and assert it
received no model call.

* test(llm-deepseek): compose the malformed-key turn without the native executor

release/dsh-0.2.1 predates @deepseek-ai/dsh-tool-executor-native; its tool
runtime executes tools itself. Compose the official-route turn the way
account-routing.spec.ts does on this branch.

* fix(llm-deepseek-api-key): gate nothing when the credential lookup fails

The listing cache switches scope only after it reads a credential, so a
failed lookup left `connect` serving the previous credential's listing.
After a key whose listing refuses a model was replaced by a malformed one,
`admit` refused that model with CLIENT_UPGRADE_REQUIRED before the turn
recorded the prompt, instead of `resolveAuth` reporting the credential
error on the request. Serve the built-in catalog without listing gates
when the lookup fails.

* test(llm-deepseek-api-key): pin the once-per-listing diagnostic across request preparation

The hidden-entry diagnostic test repeated the same discovery assertion to
prove a second pass reports nothing new, which read as a duplicate. Assert
the single warning after the request preparations instead; they resolve
the same listing, so dropping the per-listing deduplication still fails
the test.

* docs(llm-deepseek-api-key): note that a list matching an earlier built-in catalog counts as customized

Customization is judged against the running version's built-in catalog,
so a saved `models` list equal to an earlier version's catalog stops
following the listing once the built-in catalog changes, until Restore
defaults. Record the consequence in the Agent Note and the README's known
limitations.
2026-10-22 20:42:19 +08:00
Turtle 77b2d919c4 docs(plugin-market): fix index wording left by the rename 2026-10-22 20:42:15 +08:00
Turtle 6c07e02afa fix(plugin-market): finish the plugin index wording and restore generated docs 2026-10-22 20:20:02 +08:00
Turtle 5b0e089f40 fix(plugin-market): present custom plugin markets as custom plugin indexes 2026-10-22 20:19:30 +08:00
imccyu 39d2903841 fix(ui): separate navigation pins from selection and show menu icons (#6883)
* fix(ui): separate navigation pins from selection and show menu icons

* fix(ui): simplify More menus and fold conversation views on resize

* test(ui): fix navigation CI regressions and refresh catalogs

* refactor(ui): render sidebar panel icons directly

* fix(ui): keep Chat visible and stop persisting navigation pins

* refactor(ui): drop unreachable pin validation from in-memory stores
2026-10-22 20:05:33 +08:00
imccyu 2ae65c16b7 Merge pull request #6966 from deepseek-harness/revert-6959-xtr/fix-web-agent-initialization
Revert "fix(session-controller): 在 Web 操作中等待本地 Agent 初始化"
2026-10-22 18:18:43 +08:00
imccyu f185b5fa6d Revert "fix(session-controller): 在 Web 操作中等待本地 Agent 初始化" 2026-10-22 18:18:01 +08:00
_Kerman a3d5e4f9e3 Merge pull request #6959 from deepseek-harness/xtr/fix-web-agent-initialization
fix(session-controller): 在 Web 操作中等待本地 Agent 初始化
2026-10-22 18:12:26 +08:00
_Kerman d3972b1af5 fix(session-controller): handle initialization join failures 2026-10-22 17:44:40 +08:00
Chinesezjc 43f4c9a4ee Merge pull request #6789 from deepseek-harness/work/restore-subagent-end-turn
fix(prompt): end the turn while waiting on subagents
2026-10-22 17:35:12 +08:00
Magolor a9dd195400 refactor(approval): persist policy and turn state in projection (#6816)
* refactor(approval): persist policy and turn state in projection

* fix(approval): require ready projection state and host-owned recovery

* chore(approval): retire obsolete test cast allowances

* docs(approval): make activation migration requirement explicit

* docs(session-projection): clarify recovery ownership and readiness

* docs(approval): keep projection skill in dedicated PR
2026-10-22 17:27:54 +08:00
Chinesezjc 3b30f69c9f test(snapshot): carry the end-turn guidance into merged scenarios
The branch merge from master brought four scenarios added after the prompt
refresh (background-wait-steer, session-resume, model-switch-compaction,
web-search-unconfigured); their system-prompt sidecars still show the
guidance without the restored sentence, so the keyless replay fails. Apply
the same sentence to those six expected lines.
2026-10-22 17:17:06 +08:00