Skip to content

Commit e5ac6f6

Browse files
authored
Add queryable history, hidden compaction, and runtime observation (#8)
* Add queryable runtime persistence with GRDB store * Improve demo logging and ignore cancellation noise * Externalize attachments and smooth demo streaming * Migrate SQLiteMemoryStore to GRDB * Refactor demo helpers and memory store collaborators * Add hidden context compaction and clean up GRDB queries * Refresh docs for GRDB storage and context compaction * Fix demo shortcuts persona reference * Refactor runtime modules and add Combine observations * Add Combine state publishers for runtime observation * Add demo observation flow and thread title editing * Document iOS and macOS platform support * Add demo turn activity indicator * Use GRDB requests for memory store mutations * Update demo Xcode project settings * Refactor GRDB store collaborators and schema * Refactor responses turn runner and transport parsing * Add runtime thread context usage projection * Refresh docs for token-based context usage
1 parent da8b897 commit e5ac6f6

77 files changed

Lines changed: 11497 additions & 3640 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ iOSInjectionProject/
102102
!*/xcshareddata/swiftpm/Package.resolved
103103
### Xcode Patch ###
104104
**/xcshareddata/WorkspaceSettings.xcsettings
105+
DemoApp/AssistantRuntimeDemoApp.xcodeproj/project.xcworkspace/
105106

106107
#Cocoapods
107108
Pods/

DemoApp/AssistantRuntimeDemoApp.xcodeproj/project.pbxproj

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 46;
6+
objectVersion = 60;
77
objects = {
88

99
/* Begin PBXBuildFile section */
@@ -25,6 +25,10 @@
2525
1A2B3C4D5E6F700000000010 /* DemoMemoryExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2B3C4D5E6F700000000010 /* DemoMemoryExamples.swift */; };
2626
1A2B3C4D5E6F700000000011 /* AgentDemoViewModel+Memory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2B3C4D5E6F700000000011 /* AgentDemoViewModel+Memory.swift */; };
2727
1A2B3C4D5E6F700000000012 /* MemoryDemoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2B3C4D5E6F700000000012 /* MemoryDemoView.swift */; };
28+
1A2B3C4D5E6F700000000013 /* AgentDemoViewModel+ComposerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2B3C4D5E6F700000000013 /* AgentDemoViewModel+ComposerState.swift */; };
29+
1A2B3C4D5E6F700000000014 /* AgentDemoViewModel+ThreadState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2B3C4D5E6F700000000014 /* AgentDemoViewModel+ThreadState.swift */; };
30+
1A2B3C4D5E6F700000000015 /* AgentDemoViewModel+Observation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2B3C4D5E6F700000000015 /* AgentDemoViewModel+Observation.swift */; };
31+
1A2B3C4D5E6F700000000016 /* ThreadTurnActivityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2B3C4D5E6F700000000016 /* ThreadTurnActivityView.swift */; };
2832
7482123BC63AC10F104DE092 /* AssistantRuntimeDemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A6999E6475919476E726E8C /* AssistantRuntimeDemoApp.swift */; };
2933
84726927B752451499D9257F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 906A95007C8ECB92CFC2CE15 /* Foundation.framework */; };
3034
B060448C6464C41789B56EED /* AgentDemoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CA22585116A120BA97F76B8 /* AgentDemoView.swift */; };
@@ -35,6 +39,7 @@
3539
/* End PBXBuildFile section */
3640

3741
/* Begin PBXFileReference section */
42+
2481147A958D00EB4A70C928 /* AgentDemoViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AgentDemoViewModel.swift; sourceTree = "<group>"; };
3843
2A2B3C4D5E6F700000000001 /* AgentDemoView+ChatSections.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "AgentDemoView+ChatSections.swift"; sourceTree = "<group>"; };
3944
2A2B3C4D5E6F700000000002 /* AgentDemoView+ComposerAndSheets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "AgentDemoView+ComposerAndSheets.swift"; sourceTree = "<group>"; };
4045
2A2B3C4D5E6F700000000003 /* HealthCoachView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = HealthCoachView.swift; sourceTree = "<group>"; };
@@ -53,7 +58,10 @@
5358
2A2B3C4D5E6F700000000010 /* DemoMemoryExamples.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DemoMemoryExamples.swift; sourceTree = "<group>"; };
5459
2A2B3C4D5E6F700000000011 /* AgentDemoViewModel+Memory.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "AgentDemoViewModel+Memory.swift"; sourceTree = "<group>"; };
5560
2A2B3C4D5E6F700000000012 /* MemoryDemoView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MemoryDemoView.swift; sourceTree = "<group>"; };
56-
2481147A958D00EB4A70C928 /* AgentDemoViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AgentDemoViewModel.swift; sourceTree = "<group>"; };
61+
2A2B3C4D5E6F700000000013 /* AgentDemoViewModel+ComposerState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "AgentDemoViewModel+ComposerState.swift"; sourceTree = "<group>"; };
62+
2A2B3C4D5E6F700000000014 /* AgentDemoViewModel+ThreadState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "AgentDemoViewModel+ThreadState.swift"; sourceTree = "<group>"; };
63+
2A2B3C4D5E6F700000000015 /* AgentDemoViewModel+Observation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "AgentDemoViewModel+Observation.swift"; sourceTree = "<group>"; };
64+
2A2B3C4D5E6F700000000016 /* ThreadTurnActivityView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ThreadTurnActivityView.swift; sourceTree = "<group>"; };
5765
3CA22585116A120BA97F76B8 /* AgentDemoView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AgentDemoView.swift; sourceTree = "<group>"; };
5866
5A6999E6475919476E726E8C /* AssistantRuntimeDemoApp.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AssistantRuntimeDemoApp.swift; sourceTree = "<group>"; };
5967
690A3E5A03E545F88FAF9A44 /* AssistantRuntimeDemoApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AssistantRuntimeDemoApp.entitlements; sourceTree = "<group>"; };
@@ -85,7 +93,6 @@
8593
690A3E5A03E545F88FAF9A44 /* AssistantRuntimeDemoApp.entitlements */,
8694
FE27E9F3273C1EAF47AE5198 /* Info.plist */,
8795
);
88-
name = AssistantRuntimeDemoApp;
8996
path = AssistantRuntimeDemoApp;
9097
sourceTree = "<group>";
9198
};
@@ -133,6 +140,9 @@
133140
2A2B3C4D5E6F700000000004 /* DeviceCodePromptView.swift */,
134141
2A2B3C4D5E6F700000000005 /* Image+PlatformInit.swift */,
135142
2481147A958D00EB4A70C928 /* AgentDemoViewModel.swift */,
143+
2A2B3C4D5E6F700000000013 /* AgentDemoViewModel+ComposerState.swift */,
144+
2A2B3C4D5E6F700000000014 /* AgentDemoViewModel+ThreadState.swift */,
145+
2A2B3C4D5E6F700000000015 /* AgentDemoViewModel+Observation.swift */,
136146
2A2B3C4D5E6F700000000006 /* AgentDemoViewModel+Messaging.swift */,
137147
2A2B3C4D5E6F700000000007 /* AgentDemoViewModel+Tools.swift */,
138148
2A2B3C4D5E6F700000000008 /* AgentDemoViewModel+HealthCoach.swift */,
@@ -143,11 +153,11 @@
143153
2A2B3C4D5E6F70000000000D /* DemoUIComponents.swift */,
144154
2A2B3C4D5E6F70000000000E /* StructuredOutputDemoView.swift */,
145155
2A2B3C4D5E6F70000000000F /* ThreadDetailView.swift */,
156+
2A2B3C4D5E6F700000000016 /* ThreadTurnActivityView.swift */,
146157
2A2B3C4D5E6F700000000010 /* DemoMemoryExamples.swift */,
147158
2A2B3C4D5E6F700000000011 /* AgentDemoViewModel+Memory.swift */,
148159
2A2B3C4D5E6F700000000012 /* MemoryDemoView.swift */,
149160
);
150-
name = Shared;
151161
path = Shared;
152162
sourceTree = "<group>";
153163
};
@@ -181,8 +191,9 @@
181191
26901593A1B92DDA950D134D /* Project object */ = {
182192
isa = PBXProject;
183193
attributes = {
194+
BuildIndependentTargetsInParallel = YES;
184195
LastSwiftUpdateCheck = 1600;
185-
LastUpgradeCheck = 1600;
196+
LastUpgradeCheck = 2630;
186197
};
187198
buildConfigurationList = 01B4A49BA7FDE96517E1DFD0 /* Build configuration list for PBXProject "AssistantRuntimeDemoApp" */;
188199
compatibilityVersion = "Xcode 3.2";
@@ -193,11 +204,9 @@
193204
Base,
194205
);
195206
mainGroup = B7BD2AF1370DA44DA0C52952;
196-
minimizedProjectReferenceProxies = 0;
197207
packageReferences = (
198208
802CFFA933DE41B7A27EFE75 /* XCLocalSwiftPackageReference ".." */,
199209
);
200-
preferredProjectObjectVersion = 77;
201210
productRefGroup = CA88F59A68B805C4F9DA5CAA /* Products */;
202211
projectDirPath = "";
203212
projectRoot = "";
@@ -240,6 +249,10 @@
240249
1A2B3C4D5E6F700000000010 /* DemoMemoryExamples.swift in Sources */,
241250
1A2B3C4D5E6F700000000011 /* AgentDemoViewModel+Memory.swift in Sources */,
242251
1A2B3C4D5E6F700000000012 /* MemoryDemoView.swift in Sources */,
252+
1A2B3C4D5E6F700000000013 /* AgentDemoViewModel+ComposerState.swift in Sources */,
253+
1A2B3C4D5E6F700000000014 /* AgentDemoViewModel+ThreadState.swift in Sources */,
254+
1A2B3C4D5E6F700000000015 /* AgentDemoViewModel+Observation.swift in Sources */,
255+
1A2B3C4D5E6F700000000016 /* ThreadTurnActivityView.swift in Sources */,
243256
7482123BC63AC10F104DE092 /* AssistantRuntimeDemoApp.swift in Sources */,
244257
BB4F38E64D1EBBB3821AC4E3 /* AgentDemoRuntimeFactory.swift in Sources */,
245258
B060448C6464C41789B56EED /* AgentDemoView.swift in Sources */,
@@ -284,9 +297,12 @@
284297
CLANG_WARN_UNREACHABLE_CODE = YES;
285298
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
286299
COPY_PHASE_STRIP = NO;
300+
DEAD_CODE_STRIPPING = YES;
287301
DEBUG_INFORMATION_FORMAT = dwarf;
302+
DEVELOPMENT_TEAM = T9G4574SJG;
288303
ENABLE_STRICT_OBJC_MSGSEND = YES;
289304
ENABLE_TESTABILITY = YES;
305+
ENABLE_USER_SCRIPT_SANDBOXING = YES;
290306
GCC_C_LANGUAGE_STANDARD = gnu11;
291307
GCC_DYNAMIC_NO_PIC = NO;
292308
GCC_NO_COMMON_BLOCKS = YES;
@@ -305,6 +321,7 @@
305321
MTL_FAST_MATH = YES;
306322
ONLY_ACTIVE_ARCH = YES;
307323
PRODUCT_NAME = "$(TARGET_NAME)";
324+
STRING_CATALOG_GENERATE_SYMBOLS = YES;
308325
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
309326
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
310327
SWIFT_VERSION = 5.0;
@@ -320,11 +337,13 @@
320337
CLANG_ENABLE_OBJC_WEAK = NO;
321338
CODE_SIGN_ENTITLEMENTS = AssistantRuntimeDemoApp/AssistantRuntimeDemoApp.entitlements;
322339
CODE_SIGN_STYLE = Automatic;
323-
DEVELOPMENT_TEAM = T9G4574SJG;
324340
GENERATE_INFOPLIST_FILE = NO;
325341
INFOPLIST_FILE = AssistantRuntimeDemoApp/Info.plist;
326342
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
327-
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
343+
LD_RUNPATH_SEARCH_PATHS = (
344+
"$(inherited)",
345+
"@executable_path/Frameworks",
346+
);
328347
PRODUCT_BUNDLE_IDENTIFIER = ai.assistantruntime.demoapp;
329348
PRODUCT_NAME = "$(TARGET_NAME)";
330349
SDKROOT = iphoneos;
@@ -343,11 +362,13 @@
343362
CLANG_ENABLE_OBJC_WEAK = NO;
344363
CODE_SIGN_ENTITLEMENTS = AssistantRuntimeDemoApp/AssistantRuntimeDemoApp.entitlements;
345364
CODE_SIGN_STYLE = Automatic;
346-
DEVELOPMENT_TEAM = T9G4574SJG;
347365
GENERATE_INFOPLIST_FILE = NO;
348366
INFOPLIST_FILE = AssistantRuntimeDemoApp/Info.plist;
349367
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
350-
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
368+
LD_RUNPATH_SEARCH_PATHS = (
369+
"$(inherited)",
370+
"@executable_path/Frameworks",
371+
);
351372
PRODUCT_BUNDLE_IDENTIFIER = ai.assistantruntime.demoapp;
352373
PRODUCT_NAME = "$(TARGET_NAME)";
353374
SDKROOT = iphoneos;
@@ -390,9 +411,12 @@
390411
CLANG_WARN_UNREACHABLE_CODE = YES;
391412
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
392413
COPY_PHASE_STRIP = NO;
414+
DEAD_CODE_STRIPPING = YES;
393415
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
416+
DEVELOPMENT_TEAM = T9G4574SJG;
394417
ENABLE_NS_ASSERTIONS = NO;
395418
ENABLE_STRICT_OBJC_MSGSEND = YES;
419+
ENABLE_USER_SCRIPT_SANDBOXING = YES;
396420
GCC_C_LANGUAGE_STANDARD = gnu11;
397421
GCC_NO_COMMON_BLOCKS = YES;
398422
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -404,6 +428,7 @@
404428
MTL_ENABLE_DEBUG_INFO = NO;
405429
MTL_FAST_MATH = YES;
406430
PRODUCT_NAME = "$(TARGET_NAME)";
431+
STRING_CATALOG_GENERATE_SYMBOLS = YES;
407432
SWIFT_COMPILATION_MODE = wholemodule;
408433
SWIFT_OPTIMIZATION_LEVEL = "-O";
409434
SWIFT_VERSION = 5.0;

DemoApp/AssistantRuntimeDemoApp.xcodeproj/xcshareddata/xcschemes/AssistantRuntimeDemoApp.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1600"
3+
LastUpgradeVersion = "2630"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

DemoApp/AssistantRuntimeDemoApp/Shared/AgentDemoRuntimeFactory.swift

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ enum AgentDemoRuntimeFactory {
102102
)
103103
),
104104
approvalPresenter: approvalInbox,
105-
stateStore: FileRuntimeStateStore(url: stateURL ?? defaultStateURL()),
105+
stateStore: try! GRDBRuntimeStateStore(url: stateURL ?? defaultStateURL()),
106106
memory: .init(
107107
store: try! SQLiteMemoryStore(url: defaultMemoryURL()),
108108
automaticCapturePolicy: .init(
@@ -116,6 +116,16 @@ enum AgentDemoRuntimeFactory {
116116
maxMemories: 2
117117
)
118118
)
119+
),
120+
contextCompaction: AgentContextCompactionConfiguration(
121+
isEnabled: true,
122+
mode: .automatic,
123+
visibility: .hidden,
124+
strategy: .preferRemoteThenLocal,
125+
trigger: .init(
126+
estimatedTokenThreshold: 2_000,
127+
retryOnContextLimitError: true
128+
)
119129
)
120130
))
121131
}
@@ -143,7 +153,7 @@ enum AgentDemoRuntimeFactory {
143153
)
144154
),
145155
approvalPresenter: NonInteractiveApprovalPresenter(),
146-
stateStore: FileRuntimeStateStore(url: defaultStateURL()),
156+
stateStore: try! GRDBRuntimeStateStore(url: defaultStateURL()),
147157
memory: .init(
148158
store: try! SQLiteMemoryStore(url: defaultMemoryURL()),
149159
automaticCapturePolicy: .init(
@@ -157,6 +167,16 @@ enum AgentDemoRuntimeFactory {
157167
maxMemories: 2
158168
)
159169
)
170+
),
171+
contextCompaction: AgentContextCompactionConfiguration(
172+
isEnabled: true,
173+
mode: .automatic,
174+
visibility: .hidden,
175+
strategy: .preferRemoteThenLocal,
176+
trigger: .init(
177+
estimatedTokenThreshold: 2_000,
178+
retryOnContextLimitError: true
179+
)
160180
)
161181
))
162182
}
@@ -169,7 +189,7 @@ enum AgentDemoRuntimeFactory {
169189

170190
return baseDirectory
171191
.appendingPathComponent("AssistantRuntimeDemoApp", isDirectory: true)
172-
.appendingPathComponent("runtime-state.json")
192+
.appendingPathComponent("runtime-state.sqlite")
173193
}
174194

175195
static func defaultMemoryURL() -> URL {

DemoApp/AssistantRuntimeDemoApp/Shared/AgentDemoView+ChatSections.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,23 @@ extension AgentDemoView {
4141
.foregroundStyle(.secondary)
4242
}
4343

44+
Toggle(
45+
"Developer Logging",
46+
isOn: Binding(
47+
get: { viewModel.developerLoggingEnabled },
48+
set: { viewModel.developerLoggingEnabled = $0 }
49+
)
50+
)
51+
.toggleStyle(.switch)
52+
53+
Text("Debug builds start with logging enabled. Logs print to the Xcode console for restore, sign-in, thread lifecycle, turn events, and tool activity.")
54+
.font(.caption)
55+
.foregroundStyle(.secondary)
56+
57+
Text("State store: \(viewModel.resolvedStateURL.lastPathComponent)")
58+
.font(.caption.monospaced())
59+
.foregroundStyle(.secondary)
60+
4461
LazyVGrid(columns: tileColumns, spacing: 12) {
4562
registerToolTile
4663

@@ -88,7 +105,6 @@ extension AgentDemoView {
88105
Text("Pick a thinking level for future requests. Existing threads stay intact; only new turns use the updated effort.")
89106
.font(.subheadline)
90107
.foregroundStyle(.secondary)
91-
92108
LazyVGrid(columns: tileColumns, spacing: 12) {
93109
ForEach(ReasoningEffort.allCases, id: \.self) { effort in
94110
reasoningEffortTile(for: effort)

DemoApp/AssistantRuntimeDemoApp/Shared/AgentDemoView.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ struct AgentDemoView: View {
3232
#endif
3333
.task {
3434
await viewModel.restore()
35-
await viewModel.registerDemoTool()
3635
}
3736
.sheet(item: approvalRequestBinding) { request in
3837
approvalSheet(for: request)

0 commit comments

Comments
 (0)