源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
package agentruntime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
activityshared "github.com/tutti-os/tutti/packages/agent/daemon/activity/events"
|
||||
)
|
||||
|
||||
type providerDispatchObserver struct {
|
||||
once sync.Once
|
||||
result chan providerDispatchObservation
|
||||
}
|
||||
|
||||
type providerDispatchObservation struct {
|
||||
dispatch ProviderDispatchResult
|
||||
err error
|
||||
}
|
||||
|
||||
func newProviderDispatchObserver() *providerDispatchObserver {
|
||||
return &providerDispatchObserver{
|
||||
result: make(chan providerDispatchObservation, 1),
|
||||
}
|
||||
}
|
||||
|
||||
func (observer *providerDispatchObserver) Report(result ProviderDispatchResult) {
|
||||
observer.ReportWithError(result, nil)
|
||||
}
|
||||
|
||||
func (observer *providerDispatchObserver) ReportWithError(result ProviderDispatchResult, err error) {
|
||||
if observer == nil {
|
||||
return
|
||||
}
|
||||
observer.once.Do(func() {
|
||||
observer.result <- providerDispatchObservation{
|
||||
dispatch: result,
|
||||
err: err,
|
||||
}
|
||||
close(observer.result)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Controller) confirmProviderDispatchDurable(
|
||||
ctx context.Context,
|
||||
session Session,
|
||||
turnID string,
|
||||
dispatch ProviderDispatchResult,
|
||||
) (ProviderDispatchResult, error) {
|
||||
if dispatch.Disposition != DispatchDispositionApplied || dispatch.Acceptance == nil {
|
||||
return dispatch, nil
|
||||
}
|
||||
receipt := *dispatch.Acceptance
|
||||
if receipt.Source != AcceptanceSourceTurnStartResponse ||
|
||||
strings.TrimSpace(receipt.ProviderSessionID) == "" ||
|
||||
strings.TrimSpace(receipt.ProviderTurnID) == "" ||
|
||||
strings.TrimSpace(receipt.ProviderSessionID) !=
|
||||
strings.TrimSpace(session.ProviderSessionID) {
|
||||
return ProviderDispatchResult{
|
||||
Disposition: DispatchDispositionOutcomeUnknown,
|
||||
Acceptance: &receipt,
|
||||
AcceptanceDiagnostics: dispatch.AcceptanceDiagnostics,
|
||||
}, errors.New("provider dispatch returned an invalid acceptance receipt")
|
||||
}
|
||||
eventContext, ok := activityEventContext(
|
||||
session,
|
||||
"root-provider-turn-started:"+strings.TrimSpace(receipt.ProviderTurnID),
|
||||
turnID,
|
||||
)
|
||||
if !ok {
|
||||
return ProviderDispatchResult{
|
||||
Disposition: DispatchDispositionOutcomeUnknown,
|
||||
Acceptance: &receipt,
|
||||
}, ErrSessionDisconnected
|
||||
}
|
||||
accepted := activityshared.NewRootProviderTurnStarted(
|
||||
eventContext,
|
||||
turnID,
|
||||
receipt.ProviderTurnID,
|
||||
)
|
||||
accepted.Payload.ProviderTurnBindingJSON = c.providerTurnBindingJSON(
|
||||
ctx,
|
||||
session,
|
||||
ProviderTurnBindingWriteInput{
|
||||
Kind: ProviderTurnBindingWriteStarted,
|
||||
ProviderTurnID: receipt.ProviderTurnID,
|
||||
},
|
||||
)
|
||||
accepted.Payload.Metadata = map[string]any{
|
||||
"acceptanceSource": string(receipt.Source),
|
||||
}
|
||||
// Preserve the stamped ProviderInputUnit from the live provider event so the
|
||||
// acceptance commit carries Replay batches. Without it, Claude Code's later
|
||||
// re-emit is often an empty-mutation no-op (no TransactionID) and
|
||||
// checkpoint_commit_unconfirmed fails for turn.working.
|
||||
accepted.ProviderInputUnit = receipt.ProviderInputUnit
|
||||
reported, err := c.reportProviderAcceptanceDurable(ctx, session, []activityshared.Event{accepted})
|
||||
if err != nil {
|
||||
return ProviderDispatchResult{
|
||||
Disposition: DispatchDispositionOutcomeUnknown,
|
||||
Acceptance: &receipt,
|
||||
AcceptanceDiagnostics: providerAcceptanceDurabilityFailureDiagnostics(dispatch.AcceptanceDiagnostics),
|
||||
}, err
|
||||
}
|
||||
if !reported {
|
||||
return ProviderDispatchResult{
|
||||
Disposition: DispatchDispositionOutcomeUnknown,
|
||||
Acceptance: &receipt,
|
||||
AcceptanceDiagnostics: providerAcceptanceDurabilityFailureDiagnostics(dispatch.AcceptanceDiagnostics),
|
||||
}, errors.New("durable provider acceptance reporter is unavailable")
|
||||
}
|
||||
return dispatch, nil
|
||||
}
|
||||
|
||||
func providerAcceptanceDurabilityFailureDiagnostics(
|
||||
diagnostics *ProviderAcceptanceDiagnostics,
|
||||
) *ProviderAcceptanceDiagnostics {
|
||||
if diagnostics == nil {
|
||||
return &ProviderAcceptanceDiagnostics{
|
||||
Status: "durable_acceptance_failed",
|
||||
FailureReason: "durable_provider_acceptance_failed",
|
||||
}
|
||||
}
|
||||
copy := *diagnostics
|
||||
copy.Status = "durable_acceptance_failed"
|
||||
copy.FailureReason = "durable_provider_acceptance_failed"
|
||||
return ©
|
||||
}
|
||||
Reference in New Issue
Block a user